package types

import (
	"bufio"
	units "github.com/docker/go-units"
	"io"
	"net"

	"xemo.top/docker/docker/api/types/container"
	"xemo.top/docker/docker/api/types/filters"
)

// CheckpointCreateOptions 包含从容器创建检查点的参数
// CheckpointCreateOptions holds parameters to create a checkpoint from a container
type CheckpointCreateOptions struct {
	CheckpointID  string
	CheckpointDir string
	Exit          bool
}

// CheckpointListOptions 包含用于列出容器检查点的参数
// CheckpointListOptions holds parameters to list checkpoints for a container
type CheckpointListOptions struct {
	CheckpointDir string
}

// CheckpointDeleteOptions 包含从容器中删除检查点的参数
// CheckpointDeleteOptions holds parameters to delete a checkpoint from a container
type CheckpointDeleteOptions struct {
	CheckpointId  string
	CheckpointDir string
}

// ContainerAttachOptions 包含要附加到容器的参数
// ContainerAttachOptions holds parameters to attach to a container.
type ContainerAttachOptions struct {
	Stream     bool
	Stdin      bool
	Stdout     bool
	Stderr     bool
	DetachKeys string
	Logs       bool
}

// ContainerCommitOptions 包含将更改提交到容器中的参数
// ContainerCommitOptions holds parameters to commit changes into a container
type ContainerCommitOptions struct {
	Reference string
	Comment   string
	Author    string
	Changes   []string
	Pause     bool
	Config    *container.Config
}

// HijackedResponse 保存被劫持请求的连接信息
// HijackedResponse holds connection information for a hijacked request
type HijackedResponse struct {
	Conn   net.Conn
	Reader *bufio.Reader
}

// ContainerExecInspect保存exec inspect返回的信息
// ContainerExecInspect holds information returned by exec inspect
type ContainerExecInspect struct {
	ExecID      string
	ContainerID string
	Running     bool
	ExitCode    int
	Pid         int
}

// ResizeOptions包含调整tty大小的参数。
// ResizeOptions holds parameters to resize a tty.
// 它也可以用来调整容器ttys的大小和执行进程ttys
// It can be used to resize container ttys and exec process ttys too
type ResizeOptions struct {
	Height uint
	Width  uint
}

// ContainerListOptions 包含用于列出容器的参数
// ContainerListOptions holds parameters to list containers with
type ContainerListOptions struct {
	Quiet   bool
	Size    bool
	All     bool
	Latest  bool
	Since   string
	Before  string
	Limit   int
	Filters filters.Args
}

// ContainerLogsOptions holds parameters  to filter logs with.
type ContainerLogsOptions struct {
	ShowStdout bool
	ShowStderr bool
	Since      string
	Until      string
	Timestamps bool
	Follow     bool
	Tail       string
	Details    bool
}

// ContainerRemoveOptions holds parameters to remove
type ContainerRemoveOptions struct {
	RemoveVolumes bool
	RemoveLinks   bool
	Force         bool
}

// ContainerStartOptions holds parameters to start containers
type ContainerStartOptions struct {
	CheckpointID  string
	CheckpointDir string
}

// CopyToContainerOptions holds information about files to copy into a container
type CopyToContainerOptions struct {
	AllowOverwriteDirWithFile bool
	CopyUIDGID                bool
}

// BuilderVersion sets the version of underlying builder to use
// BuilderVersion 设置要使用的底层构建器的版本
type BuilderVersion string

const (
	// BuilderV1 is the first generation builder in docker daemon
	BuilderV1 BuilderVersion = "1"
	// BuilderBuildKit is builder based on moby/buildkit project
	BuilderBuildKit = "2"
)

// ImageBuildOptions 保存构建图像所需的信息。
// ImageBuildOptions holds the information necessary to build images.
type ImageBuildOptions struct {
	Tags           []string
	suppressOutput bool
	RemoteContext  string
	NoCache        bool
	Remove         bool
	ForceRemove    bool
	PullParent     bool
	Isolation      container.Isolation
	CPUSetCPUs     string
	CPUSetMems     string
	CPUShares      int64
	CPUQuota       int64
	CPUPeriod      int64
	Memory         int64
	MemorySwap     int64
	CgroupParent   string
	NetworkMode    string
	ShmSize        int64
	Dockerfile     string
	Ulimits        []*units.Ulimit
	// BuildArgs 需要是一个 * 字符串，而不仅仅是一个字符串，这样我们就可以分辨 “” (空字符串) 和根本没有值 (nil) 之间的区别，请参阅api/server/router/build_routes.go中的buildArgs解析以获取更多信息。
	// BuildArgs needs to be a *string instead of just a string so that we can tell the difference between "" (empty string) and no value at all (nil),See the parsing of buildArgs in api/server/router/build_routes.go for even more info.
	BuildArgs   map[string]*string
	AuthConfigs map[string]AuthConfig
	Context     io.Reader
	Labels      map[string]string
	// squash 生成的图像的图层到父级会保留原始图像，并从父级创建一个新图像，并将所有更改应用于单个图层。
	// squash the resulting image's layers to the parent preserves the original image and creates a new one from the parent with all the changes applied to a single layer.
	Squash bool
	// CacheFrom 指定用于匹配缓存的图像。此处指定的图像不需要具有有效的父链来匹配缓存
	// CacheFrom specifies images that are used for matching cache. Images specified here do not need to have a valid parent chain to match cache
	CacheFrom   []string
	SecurityOpt []string
	// List of extra hosts
	ExtraHosts []string
	Target     string
	SessionID  string
	Platform   string
	// Version 指定要使用的unerleing builder的版本
	// Version specifies the version of the unerlying builder to use
	Version BuilderVersion
	// BuildID 是可与生成请求一起传递的可选标识符。相同的标识符可用于通过取消请求正常取消生成。
	// BuildID is an optional identifier that can be passed together with the build request.The same identifier can be used to gracefully cancel the build with the cancel request.
	BuildID string
	// Outputs 定义用于导出生成结果的配置。仅在BuildKit模式下支持
	// Outputs defines configurations for exporting build results.Only supported in BuildKit mode
	Options []ImageBuildOutput
}

// ImageBuildOutput 定义用于导出生成结果的配置
// ImageBuildOutput defines configuration for exporting a build result
type ImageBuildOutput struct {
	Type  string
	Attrs map[string]string
}

// ImageBuildResponse 保存服务器在构建映像后返回的信息。
// ImageBuildResponse holds information returned by a server after building an image.
type ImageBuildResponse struct {
	Body   io.ReadCloser
	OSType string
}

// ImageCreateOptions 保存用于创建图像的信息。
// ImageCreateOptions holds information to create images.
type ImageCreateOptions struct {
	// RegistryAuth 是注册表的base64编码凭据。
	// RegistryAuth is the base64 encoded credentials for the registry.
	RegistryAuth string
	// Platform 是映像的目标平台 (如果需要从注册表中提取)。
	// Platform is the target platform of the image if it needs to be pulled from the registry.
	Platform string
}

// ImageListOptions 保存用于过滤图像列表的参数。
// ImageListOptions holds parameters to filter the list of images with.
type ImageListOptions struct {
	All     bool
	Filters filters.Args
}

// ImageLoadResponse 向客户端返回有关加载进程的信息。
// ImageLoadResponse returns information to the client about a load process.
type ImageLoadResponse struct {
	// Body 必须关闭以避免资源泄漏
	// Body must be closed to avoid a resource leak
	Body io.ReadCloser
	JSON bool
}

// ImagePullOptions 保存提取图像的信息。
// ImagePullOptions holds information to pull images.
type ImagePullOptions struct {
	All bool
	// RegistryAuth 是注册表的base64编码凭据
	// RegistryAuth is the base64 encoded credentials for the registry
	RegistryAuth  string
	PrivilegeFunc RequestPrivilegeFunc
	Platform      string
}

// RequestPrivilegeFunc 是一个函数接口，客户端可以在获得授权错误后提供该接口以重试操作。此函数以base64格式返回注册表身份验证标头值，如果权限请求失败，则返回错误。
// RequestPrivilegeFunc is a function interface that clients can supply to retry operations after getting an authorization error. This function returns the registry authentication header value in base64 format,or an error if the privilege request fails.
type RequestPrivilegeFunc func() (string, error)

// ImagePushOptions holds information to push images.
type ImagePushOptions ImagePullOptions

// ImageRemoveOptions holds parameters to remove images
type ImageRemoveOptions struct {
	Force         bool
	PruneChildren bool
}

// ImageSearchOptions holds parameters to search images with.
type ImageSearchOptions struct {
	RegistryAuth  string
	PrivilegeFunc RequestPrivilegeFunc
	Filters       filters.Args
	Limit         int
}

// NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct {
	Filters filters.Args
}

// NodeRemoveOptions holds parameters to remove nodes with.
type NodeRemoveOptions struct {
	Force bool
}

// NetworkListOptions 保存用于过滤网络列表的参数
// NetworkListOptions holds parameters to filter the list of networks with
type NetworkListOptions struct {
	Filters filters.Args
}

// PluginRemoveOptions holds parameters to remove plugins
type PluginRemoveOptions struct {
	Force bool
}

// PluginEnableOptions holds parameters to enable plugins
type PluginEnableOptions struct {
	Timeout int
}

// PluginDisableOptions holds parameters to enable plugins
type PluginDisableOptions struct {
	Force bool
}

// PluginInstallOptions holds parameters to install a plugin.
type PluginInstallOptions struct {
	Disabled             bool
	AcceptAllPermissions bool
	// RegistryAuth 是注册表的base64编码凭据
	// RegistryAuth is the base64 encoded credentials for the registry
	RegistryAuth string
	// RemoteRef 是注册表上的插件名称
	// RemoteRef is the plugin name on the registry
	RemoteRef            string
	PrivilegeFunc        RequestPrivilegeFunc
	AcceptPermissionFunc func(PluginPrivileges) (bool, error)
	Args                 []string
}

// PluginCreateOptions hold all options to plugin create.
type PluginCreateOptions struct {
	RepoName string
}

// ServiceCreateOptions 包含创建服务时要使用的选项
// ServiceCreateOptions contains the options to use when creating a service
type ServiceCreateOptions struct {
	// EncodedRegistryAuth 更新服务时要使用的编码的注册表授权凭据。
	// EncodedRegistryAuth is the encoded registry authorization credentials to use when updating the service.
	//
	// 该字段遵循x-registry-auth报头的格式。
	// This field follows the format of the X-Registry-Auth header.
	EncodedRegistryAuth string
	// QueryRegistry 指示服务更新是否需要联系注册表。可以联系注册表以检索映像摘要和清单，这些映像摘要和清单又可用于更新平台或有关服务的其他信息
	// QueryRegistry indicates whether the service update requires contacting a registry. A registry may be contacted to retrieve the image digest and manifest,which in turn can be used to update platform or other information about the service
	QueryRegistry bool
}

// ServiceCreateResponse 包含在创建新服务时返回给客户端的信息。
// ServiceCreateResponse contains the information returned to a client on the creation of a new service.
type ServiceCreateResponse struct {
	// ID is the ID of the created service
	ID string
	// Warnings 是一组传递给用户的非致命警告消息。
	// Warnings is a set of non-fatal warning messages to pass on to the user.
	Warnings []string `json:",omitempty"`
}

// ServiceInspectOptions 保存与 “服务检查” 操作相关的参数。
// ServiceInspectOptions holds parameters related to the "service inspect" operation.
type ServiceInspectOptions struct {
	InsertDefaults bool
}

// ServiceListOptions holds parameters to list services with
type ServiceListOptions struct {
	Filters filters.Args
}

// ServiceUpdateOptions 包含用于更新服务的选项。
// ServiceUpdateOptions contains the options to be used for updating services.
type ServiceUpdateOptions struct {
	// EncodeRegistryAuth 是更新服务时要使用的编码的注册表授权凭据
	// EncodeRegistryAuth is the encoded registry authorization credentials to use when updating the service
	//
	// 该字段遵循x-registry-auth报头的格式。
	// This field follows the format of the X-Registry-Auth header.
	EncodeRegistryAuth string

	// TODO(stevvooe): 考虑将ServiceUpdate的version参数移到此字段中。虽然它确实开放API用户进行快速写入，但大多数用户在实践中可能不需要该级别的一致性。
	// TODO(stevvooe): Consider moving the version parameter of ServiceUpdate into this field.While it does open API users up to racy writes,most users may not need that level of consistency in practice.

	// RegistryAuthFrom 指定在EncodeRegistryAuth中未给出注册表授权凭据的位置。有效值为 “spec” 和 “previous-spec”
	// RegistryAuthFrom specifies where to find the registry authorization credentials if they are not given in EncodeRegistryAuth.Valid values are "spec" and "previous-spec"
	RegistryAuthForm string

	// Rollback 指示是否应执行服务器端回滚。设置此值时，将忽略提供的规范。有效值为 “previous” 和 “none”。空值与 “none” 相同。
	// Rollback indicates whether a server-side rollback should be performed.When this is set,the provided spec will be ignored.The valid values are "previous" and "none".An empty value is the same as "none".
	Rollback string
	// QueryRegistry 指示服务更新是否需要联系注册表。可以联系注册表以检索映像摘要和清单，其进而可以用于更新关于服务的平台或其他信息。
	// QueryRegistry indicates whether the service update requires contacting a registry. A registry may be contacted to retrieve the image digest and manifest,which in turn can be used to update platform or other information about the service.
	QueryRegistry bool
}

// TaskListOptions holds parameters to list tasks with.
type TaskListOptions struct {
	Filters filters.Args
}

// SwarmUnlockKeyResponse contains the response for Engine API: GET /swarm/unlockkey
type SwarmUnlockKeyResponse struct {
	// UnlockKey 解锁密钥是否为ASCII装甲格式
	// UnlockKey is the unlock key in ASCII-armored format
	UnlockKey string
}

// CloseWriter 是一个实现结构的接口，该结构关闭输入流以防止写入
// CloseWriter is an interface that implements structs that close input streams to prevent from writing
type CloseWriter interface {
	CloseWrite() error
}

// CloseWrite closes a readWriter for writing.
func (h *HijackedResponse) CloseWrite() error {
	if conn, ok := h.Conn.(CloseWriter); ok {
		return conn.CloseWrite()
	}
	return nil
}
